import log from 'fancy-log';
import chalk from 'chalk';

import { ConverterOptions, SVGFontToTTFFontConverter, SVGToSVGFontConverter } from './converter';
import { DefaultSVGFontToTTFFontConverter } from './converter/svgfont-to-ttffont.converter';
import { DefaultFontConvertOptions } from './converter/constants';
import { DefaultTTFFontToEOFFontConverter } from './converter/ttffont-to-eoffont.converter';
import { DefaultTTFFontToWOFFFontConverter } from './converter/ttffont-to-wofffont.converter';
import { DefaultTTFFontToWOFF2FontConverter } from './converter/ttffont-to-woff2font.converter';
import { writeFileTo } from './utils/file.utils';
import { getFilePath } from './utils/path.utils';
import { FontExtension } from './converter/types';
import { DefaultMetaToCSSConverter } from './converter/meta-to-css.converter';

async function convertSVG(options?: ConverterOptions) {
    try {
        log(chalk.green('Start Generated Font...'));

        const fontOptions = Object.assign({}, DefaultFontConvertOptions, options);

        const convertResult = await new SVGToSVGFontConverter(fontOptions).convert();

        const ttfBuffer = DefaultSVGFontToTTFFontConverter.convert(convertResult?.fontData);
        await writeFile(ttfBuffer, fontOptions, 'ttf');

        const metaDataOptions: ConverterOptions = {
            formDir: '',
            outDir: fontOptions.outDir,
            fontName: 'svg-icon-font.mapping',
        };
        await writeFile(Buffer.from(JSON.stringify(convertResult.metaMapping, null, 4)), metaDataOptions, 'json');

        const eofBuffer = fontOptions?.fontExts?.includes('eof') && DefaultTTFFontToEOFFontConverter.convert(ttfBuffer);
        await writeFile(eofBuffer, fontOptions, 'eof');

        const woffBuffer =
            fontOptions?.fontExts?.includes('woff') && DefaultTTFFontToWOFFFontConverter.convert(ttfBuffer);
        await writeFile(woffBuffer, fontOptions, 'woff');

        const woff2Buffer =
            fontOptions?.fontExts?.includes('woff2') && DefaultTTFFontToWOFF2FontConverter.convert(ttfBuffer);
        await writeFile(woff2Buffer, fontOptions, 'woff2');

        const cssBuffer = await DefaultMetaToCSSConverter.convert(convertResult.metaMapping, fontOptions);

        const cssOptions: ConverterOptions = {
            formDir: '',
            outDir: fontOptions.outDir?.replace('font', 'style'),
            fontName: 'svg-icon-style',
        };
        await writeFile(cssBuffer, cssOptions, 'css');

        log(chalk.green('Generated Font Done.'));
    } catch (err) {
        log(chalk.bgRed(err));
    }
}

async function writeFile(fileData: Buffer, options: ConverterOptions, fileExtension: FontExtension | 'json' | 'css') {
    log(chalk.green(`Start write ${fileExtension?.toUpperCase()} File...`));

    const fileName = `${options.fontName}.${fileExtension}`;
    const filePath = getFilePath(options.outDir, fileName);

    await writeFileTo(filePath, fileData);

    log(chalk.green(`Congratulations, ${fileName} was Generated.`));
}

export { convertSVG };
